use std::{sync::atomic::AtomicI32, thread};
use std::sync::atomic::{AtomicBool, Ordering};

// 查看https://www.jianshu.com/p/511cde6b62a6

static X : AtomicBool = AtomicBool::new(false);
static Y : AtomicBool = AtomicBool::new(false);
static Z : AtomicI32 = AtomicI32::new(0);

fn main() {
    let t1 = thread::spawn(move || {
        write_x_then_y();
    });

    let t2 = thread::spawn(move || {
        read_y_then_x();
    });

    t1.join().unwrap();
    t2.join().unwrap();
    assert_ne!(Z.load(Ordering::SeqCst), 0);
}

fn write_x_then_y() {
    X.store(true, Ordering::Relaxed);
    Y.store(true, Ordering::Relaxed);
}

fn read_y_then_x() {
    while !Y.load(Ordering::Relaxed) {}
    if X.load(Ordering::Relaxed) {
        Z.fetch_add(1, Ordering::SeqCst);
    }
}